---
title: Architecture
summary: Layering, message dispatch path, composition root, and integration points for SAIF.Services.WCF.UC4.Host.
status: draft
owner: SAIF Doc Gen
last_reviewed: 2026-09-22
---

# Architecture

This host is a two-layer pass-through: a WCF service facade (`UC4Service`) that owns the allow/deny rule gate and logging, and a thin outbound client (`UC4Client`) that resolves the downstream address from configuration and maps the result contract. There is no repository layer, no domain layer, no persistence, no unit of work, and no dependency-injection container.

## Hosting model

The host runs in IIS. `Global.asax` instantiates a code-behind class declared in namespace `SAIF.Services.WCF.Host` (copy-paste residue from the main host, not a functional link — see [Tech debt](tech-debt.md)) deriving from `System.Web.HttpApplication`, whose `Application_Start` builds a `ServiceHostFactory` and registers the single `UC4` route. The registration detail is on [Activation and hosting](activation-hosting.md); this page covers what happens once a message is dispatched.

| Aspect | Finding |
| --- | --- |
| Host | IIS (`System.Web.HttpApplication`) — no self-host, no Windows service host |
| Application class | Declared in `Global.asax.cs`, namespace `SAIF.Services.WCF.Host` (`src/WCF/SAIF.Services.WCF.UC4.Host/Global.asax.cs`) |
| Startup call chain | `Application_Start` → construct `new ServiceHostFactory()` → `RouteTable.Routes.Add(new ServiceRoute("UC4", factory, typeof(UC4Service)))` |
| ASP.NET compatibility | `AspNetCompatibilityRequirementsMode.Allowed` |
| `aspNetCompatibilityEnabled` | true |
| Target framework | .NET Framework 4.6.2 |
| Platform target | `AnyCPU` on `Release`/`Prod`; `x64` on `Debug`/`QA` |

**Classification resolution, stated once here:** the pipeline's `AppType` marker for this host is `api`, while the sibling `SAIF.Services.WCF.Host` carries `AppType: web` — the two markers disagree inside one repository, and this host's own build template is the *web* template while its release template is the *api* template. None of these pipeline markers classifies the host. The decisive source marker is the `RouteTable.Routes.Add(new ServiceRoute("UC4", factory, typeof(UC4Service)))` call in `Global.asax.cs`, corroborated by `[AspNetCompatibilityRequirements]` on the service class and `<system.serviceModel>` in `Web.config`; on that evidence this host is documented as a WCF SOAP service, and the conflicting `api`/`frontEndApp`-style pipeline reading is recorded and overruled rather than silently discarded.

## Message dispatch path

The following diagram shows how a SOAP request reaches an operation and how the operation reaches the downstream service.

```mermaid
flowchart TD
    CALLER["SOAP caller"] --> IIS["IIS + HttpApplication"]
    IIS --> ROUTETBL["RouteTable<br>UC4 route mapping"]
    ROUTETBL --> FACTORY["ServiceHostFactory"]
    FACTORY --> HOST["ServiceHost for<br>UC4Service"]
    HOST --> BEHAVIOR["LogErrorBehavior<br>(external IServiceBehavior)"]
    BEHAVIOR --> OPER["Operation dispatched"]
    OPER --> SVC["UC4Service"]
    SVC --> GATE["IsJobAllowed<br>uc4.rules evaluation"]
    GATE -->|"blocked"| EMPTY["Return empty UC4Result<br>reason discarded"]
    GATE -->|"allowed"| CLIENT["UC4Client<br>(host-internal collaborator)"]
    CLIENT --> APICLIENTS["SAIF.Web.API.Clients<br>ClientInfo, Proxy"]
    CLIENT --> UC4PKG["SAIF.Services.UC4<br>downstream IUC4Service"]
    CLIENT --> DOWNSTREAM["Downstream UC4<br>scheduling service"]
```

<!-- No unit-of-work node is drawn: none exists in this host. The LogErrorBehavior node contributes logging, not fault shaping — see faults.md. -->

## Layer responsibilities

| Layer | Type | Responsibility |
| --- | --- | --- |
| Application class in `Global.asax.cs` | `System.Web.HttpApplication` | Application start-up and the single `UC4` route registration |
| `UC4Service` | Service implementation | Message handling, rule-based job gating, logging, parameter shaping |
| `UC4Client` | Host-internal collaborator | Resolves the downstream UC4 address from configuration, stamps caller/host identity, forwards the job, maps the downstream result |
| `SAIF.Services.UC4` / `SAIF.Web.API.Clients` | External packages | Downstream client contract, transport, and identity types* |

There is no repository/DAO layer. See [Faults and error pipeline](faults.md) for the error-handling behavior actually applied.

## Service contracts

**The `[ServiceContract]` interface source is not in scope.** `IUC4Service` is not declared anywhere in this repository; it is resolved only through `using IUC4Service = SAIF.Services.WCF.Contracts.IUC4Service;` (`src/WCF/SAIF.Services.WCF.UC4.Host/UC4Service.cs:12-13`), and is not a `<Reference>`, a `<ProjectReference>` (the project has none), or a `packages.config` entry. This is the normal state for this host, not a gap: operations are enumerated below from the `ServiceRoute` registration plus the public members of the implementing class, never from an unread contract interface.

| Service class | Declared contract | Contract location | Resolved how |
| --- | --- | --- | --- |
| `UC4Service` | `IUC4Service` (`SAIF.Services.WCF.Contracts.IUC4Service`) | External — `SAIF.Services.WCF.Contracts`, assembly identity not resolvable from this project | `using`-alias only; the assembly arrives transitively via `SAIF.Framework.Core` 2.0.23079.1* |

| Aspect | Finding |
| --- | --- |
| Contract assembly | `SAIF.Services.WCF.Contracts` (namespace) — assembly identity not resolvable from this project* |
| Present in repository | No — external |
| Arrives via | `SAIF.Framework.Core` 2.0.23079.1 (transitive)* |
| Operation surface derived from | Implementing class public members + the `UC4` route registration |
| Consequence for this document set | Operation names, parameters, and return types are read entirely from `UC4Service.cs`. Which public members carry `[OperationContract]` on the external `IUC4Service`, any `[OperationContract]` name-override attribute, and any `[FaultContract]` declarations cannot be confirmed from this repository.** |

## Composition root

| Field | Value |
| --- | --- |
| **Container present** | No — collaborators constructed directly in each operation |
| **Project** | — |
| **File** | — |
| **Entry method** | — |
| **Invoked from** | — |
| **Instance provider** | WCF default (parameterless constructor) |
| **Additional registration files** | None |

A search of this project's sources for the Autofac API surface (`new ContainerBuilder(`, `RegisterType<`, `RegisterAssemblyTypes(`, `RegisterModule`, `builder.Build(`, `: Autofac.Module`, and the bare token `Autofac`) returned zero matches, even though `Autofac` 3.5.2 is a `packages.config` entry and project reference — it is packaged and unused. `UC4Service()` (parameterless) builds `WcfEnvironmentService(OperationContext.Current.RequestContext)` and `LogService(envSvc)` directly; `UC4Client` is constructed inline inside each execute path.

## Instancing and concurrency

| Aspect | Finding |
| --- | --- |
| `InstanceContextMode` | Not declared — WCF default `PerSession` |
| `ConcurrencyMode` | Not declared — WCF default `Single` |
| Declared in | Not declared — no `[ServiceBehavior]` attribute on `UC4Service` |
| Shared mutable state | None found in code |

## Fault pipeline (summary)

`UC4Service` carries `[LogErrorBehavior]`, an `IServiceBehavior` whose type arrives from an unresolved external `SAIF.*` package (namespace `SAIF.Services.WCF.Common.Extensions`) — it is **not** the in-repository `SAIF.Services.WCF.Extensions.LogErrorBehaviorAttribute` used by the sibling `WCF` host, since this project carries no reference to that project.** No `throw new FaultException` exists anywhere in this host's source, so every failure surfaces as WCF's default fault for the thrown exception, carrying exception detail because `includeExceptionDetailInFaults="true"`. Full detail is on [Faults and error pipeline](faults.md).

## Integration points

| System | Type | Purpose |
| --- | --- | --- |
| Downstream UC4 scheduling service | External service, package-mediated | Target of every job forwarded by `UC4Client.ScheduleJob`; address resolved from `uc4coreapi.url` |
| Environment settings service | Configuration source | Supplies `uc4.rules` (allow/deny document), `uc4coreapi.url`, `uc4coreapi.schedulejobroute`, and the environment tier resolved per request from `OperationContext.RequestContext` |
| `SAIF.Framework.Core` (`SAIF.Core.Services`, `SAIF.Core.Contracts.UC4`, `SAIF.Services.WCF.Contracts`) | NuGet package | Supplies `IEnvironmentService`, `ILogService`, `UC4Result`, `UC4Environment`, and the `IUC4Service` contract* |
| `SAIF.Services.UC4` / `SAIF.Web.API.Clients` | NuGet packages | Downstream `IUC4Service` client surface, `ClientInfo`, and the `Proxy` type used by `UC4Client`* |

## Related documentation
- [Index](index.md)
- [Overview](overview.md)
- [Activation and hosting](activation-hosting.md)
- [Operations](operations.md)
- [Faults and error pipeline](faults.md)
- [Authentication and authorization](authentication-authorization.md)
- [Dependencies](dependencies.md)
- [Configuration](configuration.md)
- [Operations and processes](operations-processes.md)
- [Business rules](business-rules.md)
- [Operational runbook](operational-runbook.md)
- [Tech debt](tech-debt.md)

> **Note:** Statements marked with `*` were inferred from code structure, naming
> conventions, or contextual evidence where direct confirmation was not available
> in source artifacts. Statements marked with `**` could not be confirmed; treat
> as unknown until verified.

## Sources
- `src/WCF/SAIF.Services.WCF.UC4.Host/Global.asax.cs`
- `src/WCF/SAIF.Services.WCF.UC4.Host/UC4Service.cs`
- `src/WCF/SAIF.Services.WCF.UC4.Host/Uc4Client.cs`
- `src/WCF/SAIF.Services.WCF.UC4.Host/Web.config`
- `src/WCF/SAIF.Services.WCF.UC4.Host/SAIF.Services.WCF.UC4.Host.csproj`
- `src/WCF/SAIF.Services.WCF.UC4.Host/packages.config`
- `pipelines/build-vars.UC4.yml`
- `pipelines/release.UC4.yml`
- `pipelines/build-vars.yml` (comparison only)
